package com.floreantpos.ui.views.order;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import com.floreantpos.PosException;
import com.floreantpos.main.Application;
import com.floreantpos.model.MenuItem;
import com.floreantpos.model.MenuItemModifierGroup;
import com.floreantpos.model.MenuModifier;
import com.floreantpos.model.MenuModifierGroup;
import com.floreantpos.model.TicketItem;
import com.floreantpos.model.TicketItemModifier;
import com.floreantpos.model.TicketItemModifierGroup;
import com.floreantpos.swing.MessageDialog;
import com.floreantpos.swing.PosButton;
import com.floreantpos.ui.dialog.POSMessageDialog;
import com.floreantpos.ui.views.order.actions.ModifierSelectionListener;
import java.util.*;

/**
 *
 * @author MShahriar
 */
public class ModifierView extends SelectionView {

  private Vector<ModifierSelectionListener> listenerList = new Vector<ModifierSelectionListener>();

  private MenuItem parentMenuItem;
  private TicketItem parentTicketItem;

  private HashMap<String, ModifierButton> buttonMap = new HashMap<String, ModifierButton>();

  public static final String VIEW_NAME = "MODIFIER_VIEW";

  /**
   * Creates new form GroupView
   */
  public ModifierView() {
    super(com.floreantpos.POSConstants.MODIFIERS);
  }

  public MenuItem getMenuItem() {
    return parentMenuItem;
  }

  public void setMenuItem(MenuItem menuItem, TicketItem ticketItem) {
    this.parentMenuItem = menuItem;
    this.parentTicketItem = ticketItem;

    reset();

    try {
      List<MenuItemModifierGroup> menuItemModifierGroups = menuItem.getMenuItemModiferGroups();

      Collections.sort(menuItemModifierGroups, new Comparator() {
        public int compare(Object o1, Object o2) {
          MenuItemModifierGroup c1 = (MenuItemModifierGroup) o1;
          MenuItemModifierGroup c2 = (MenuItemModifierGroup) o2;
          return c1.toString().compareTo(c2.toString());
        }
      });

      for (Iterator<MenuItemModifierGroup> iter = menuItemModifierGroups.iterator(); iter.hasNext();) {
        MenuItemModifierGroup menuItemModifierGroup = iter.next();
        MenuModifierGroup group = menuItemModifierGroup.getModifierGroup();
        addSeparator(group.getName());

        Set<MenuModifier> modifiers = group.getModifiers();

        List<MenuModifier> modifiersList = new ArrayList<MenuModifier>(modifiers);

        Collections.sort(modifiersList, new Comparator() {
          public int compare(Object o1, Object o2) {
            MenuModifier c1 = (MenuModifier) o1;
            MenuModifier c2 = (MenuModifier) o2;
            return c1.toString().compareTo(c2.toString());
          }
        });

        int modifiersQty = 0;

        if (modifiersList.size() > 3 && Application.isDemo()) {
          modifiersQty = 3;
        } else {
          modifiersQty = modifiersList.size();
        }

        for (int i = 0; i < modifiersQty; i++) {
          MenuModifier modifier = modifiersList.get(i);
          modifier.setMenuItemModifierGroup(menuItemModifierGroup);
          ModifierButton modifierButton = new ModifierButton(modifier);
          String key = modifier.getId() + "_" + modifier.getModifierGroup().getId();
          buttonMap.put(key, modifierButton);
          addButton(modifierButton);
        }
      }
      revalidate();
      updateVisualRepresentation();
    } catch (PosException e) {
      POSMessageDialog.showError(this, com.floreantpos.POSConstants.ERROR_MESSAGE, e);
    }
  }

  public void addModifierSelectionListener(ModifierSelectionListener listener) {
    listenerList.add(listener);
  }

  public void removeModifierSelectionListener(ModifierSelectionListener listener) {
    listenerList.remove(listener);
  }

  private void fireModifierSelectionFinished() {
    for (ModifierSelectionListener listener : listenerList) {
      listener.modifierSelectionFinished(parentMenuItem);
    }
  }

  public void updateVisualRepresentation() {

    List<TicketItemModifierGroup> ticketItemModifierGroups = parentTicketItem.getTicketItemModifierGroups();
    if (ticketItemModifierGroups != null && !ticketItemModifierGroups.isEmpty()) {
      for (TicketItemModifierGroup ticketItemModifierGroup : ticketItemModifierGroups) {
        List<TicketItemModifier> ticketItemModifiers = ticketItemModifierGroup.getTicketItemModifiers();
        if (!ticketItemModifiers.isEmpty()) {
          int total = 0;
          int max = ticketItemModifierGroup.getMaxQuantity();
          for (TicketItemModifier ticketItemModifier : ticketItemModifiers) {
            String key = ticketItemModifier.getItemId() + "_" + ticketItemModifier.getGroupId();
            ModifierButton button = buttonMap.get(key);
            if (ticketItemModifier.getModifierType() != TicketItemModifier.NO_MODIFIER) {
              total = ticketItemModifier.getItemCount();
              if (total > max) {
                ticketItemModifier.setModifierType(TicketItemModifier.EXTRA_MODIFIER);
              } else {
                ticketItemModifier.setModifierType(TicketItemModifier.NORMAL_MODIFIER);
              }
            }
            button.updateView(ticketItemModifier);
          }
        }
      }
    }
  }

  public void updateVisualRepresentation(String key) {
    ModifierButton button = buttonMap.get(key);
    button.setBackground(null);
  }

  public TicketItem getParentTicketItem() {
    return parentTicketItem;
  }

  @Override
  public void doGoBack() {
    List<MenuItemModifierGroup> menuItemModifierGroups = parentMenuItem.getMenuItemModiferGroups();
    List<TicketItemModifierGroup> ticketItemModifierGroups = parentTicketItem.getTicketItemModifierGroups();

    boolean requiredModifierAdded = true;
    if (menuItemModifierGroups != null) {
      outer:
      for (MenuItemModifierGroup menuItemModifierGroup : menuItemModifierGroups) {
        int minQuantity = menuItemModifierGroup.getMinQuantity();
        if (minQuantity == 0) {
          continue;
        }

        if (ticketItemModifierGroups == null) {
          requiredModifierAdded = false;
          break outer;
        }

        for (TicketItemModifierGroup ticketItemModifierGroup : ticketItemModifierGroups) {
          if (ticketItemModifierGroup.countItems(false) < minQuantity) {
            requiredModifierAdded = false;
            break outer;
          }
        }
      }
    }

    if (!requiredModifierAdded) {
      MessageDialog.showError(com.floreantpos.POSConstants.MODIFICATIONS_WERE_NOT_INCLUDED);
      return;
    }

    fireModifierSelectionFinished();
  }

  private class ModifierButton extends PosButton implements ActionListener {

    private MenuModifier menuModifier;

    public ModifierButton(MenuModifier modifier) {
      this.menuModifier = modifier;

      if (modifier.getExtraPrice().doubleValue() != modifier.getPrice().doubleValue() && modifier.getExtraPrice() > 0) {
        setText(modifier.getName() + " - " + Application.formatNumber(modifier.getPrice()) + "/" + Application.formatNumber(modifier.getExtraPrice()));
      } else if (modifier.getExtraPrice() == 0 && modifier.getPrice() > 0) {
        setText(modifier.getName() + " - " + Application.formatNumber(modifier.getPrice()));
      } else if (modifier.getExtraPrice().doubleValue() == modifier.getPrice().doubleValue() && modifier.getPrice() > 0) {
        setText(modifier.getName() + " - " + Application.formatNumber(modifier.getPrice()));
      } else {
        setText(modifier.getName());
      }

      addActionListener(this);
    }

    void updateView(TicketItemModifier ticketItemModifier) {
      if (ticketItemModifier == null || ticketItemModifier.getModifierType() == TicketItemModifier.MODIFIER_NOT_INITIALIZED) {
        setBackground(null);
        return;
      }

      if (ticketItemModifier.getModifierType() == TicketItemModifier.NORMAL_MODIFIER) {
        setBackground(Color.GREEN.darker());
      } else if (ticketItemModifier.getModifierType() == TicketItemModifier.NO_MODIFIER) {
        setBackground(Color.RED.darker());
      } else if (ticketItemModifier.getModifierType() == TicketItemModifier.EXTRA_MODIFIER) {
        setBackground(Color.ORANGE);
      }
    }

    public void actionPerformed(ActionEvent e) {
      TicketItemModifierGroup ticketItemModifierGroup = parentTicketItem.findTicketItemModifierGroup(menuModifier, true);

      TicketItemModifier ticketItemModifier = ticketItemModifierGroup.findTicketItemModifier(menuModifier);
      TicketView ticketView = OrderView.getInstance().getTicketView();

      if (ticketItemModifier == null) {
        TicketItemModifier m = ticketItemModifierGroup.addTicketItemModifier(menuModifier, TicketItemModifier.NORMAL_MODIFIER);
        updateView(m);
        ticketView.updateAllView();
        ticketView.selectRow(m.getTableRowNum());
        return;
      }

      int modifierType = TicketItemModifier.MODIFIER_NOT_INITIALIZED;
      if (ticketItemModifier.getModifierType() != null) {
        modifierType = ticketItemModifier.getModifierType().intValue();
      }
      switch (modifierType) {
        case TicketItemModifier.MODIFIER_NOT_INITIALIZED:
          ticketItemModifier.setModifierType(TicketItemModifier.NORMAL_MODIFIER);
          updateVisualRepresentation();
          ticketView.updateAllView();
          ticketView.selectRow(ticketItemModifier.getTableRowNum());
          break;

        case TicketItemModifier.NORMAL_MODIFIER:

        case TicketItemModifier.EXTRA_MODIFIER:
          if (!ticketItemModifier.isPizzaModifier()) {
            ticketItemModifier.setModifierType(TicketItemModifier.NO_MODIFIER);
            ticketItemModifier.setItemCount(0);
            updateVisualRepresentation();
            ticketView.updateAllView();
            ticketView.selectRow(ticketItemModifier.getTableRowNum());
            break;
          }

        case TicketItemModifier.NO_MODIFIER:
          ticketItemModifier.setModifierType(TicketItemModifier.MODIFIER_NOT_INITIALIZED);
          ticketItemModifierGroup.removeTicketItemModifier(ticketItemModifier);
          updateView(ticketItemModifier);
          updateVisualRepresentation();
          ticketView.updateAllView();
          ticketView.selectRow(ticketItemModifier.getTableRowNum() - 1);
          break;
      }
    }
  }
}
